package org.yzh.rbac.component.auth;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.sample.commons.io.JsonUtils;
import org.sample.commons.lang.JWTUtils;
import org.sample.model.APIResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.yzh.rbac.component.Constant;
import org.yzh.rbac.model.enums.ResultCodes;
import org.yzh.rbac.model.vo.Token;
import org.yzh.rbac.service.PermisService;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    private static final String Forbidden = JsonUtils.toJson(new APIResult(ResultCodes.Forbidden));

    private static final String Unauthorized = JsonUtils.toJson(new APIResult(ResultCodes.Unauthorized));

    @Autowired
    private PermisService permisService;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        request.setAttribute("_beginTime", System.currentTimeMillis());
        String tokenStr = request.getHeader(Constant.TokenName);
        if (tokenStr == null)
            tokenStr = request.getParameter(Constant.TokenName);

        if (tokenStr == null) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null)
                for (Cookie cookie : cookies) {
                    if (Constant.TokenName.equals(cookie.getName()))
                        tokenStr = cookie.getValue();
                }
        }


        if (tokenStr != null) {
            Token token;
            try {
                token = JWTUtils.unsign(tokenStr, Token.class);
            } catch (TokenExpiredException e) {
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                response.getWriter().println(JsonUtils.toJson(new APIResult(ResultCodes.Unauthorized, "令牌已过期")));
                return false;
            } catch (JWTVerificationException e) {
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                response.getWriter().println(JsonUtils.toJson(new APIResult(ResultCodes.Unauthorized, "令牌格式错误[" + tokenStr + "]")));
                return false;
            }
            if (token != null) {
                request.setAttribute(Constant.TokenName, token);

//                String uri = request.getRequestURI();
//                int[] roles = token.getRoles();
//                if (roles != null)
//                    for (int role : roles) {
//                        Set<String> uris = permisService.findUriByRoleId(role);
//                        if (uris.contains(uri))
//                            return true;
//                    }
                return true;

            }
        }
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(403);
        response.getWriter().println(Unauthorized);
        return false;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}